import MIPS.Binary;

import java.util.ArrayList;

public class Pairs implements Comparable<Pairs> {
    private Kind kind;
    private String token;   //name
    private int line;
    private String type;    //int void
    private int dim;
    private ArrayList<Pairs> params;    //params/数组维度长度
    //private int len;
    private int value;
    private Boolean init;
    private int address;    //地址偏移  用于mips
    private Boolean isParam;
    private String reg;
    public ArrayList<Integer> values = new ArrayList<>();

    @Override
    public int compareTo(Pairs pairs) {
        return this.line - pairs.line;
    }

    public Pairs(Kind kind, String token) {
        this.kind = kind;
        this.token = token;
        this.dim = 0;
        this.params = new ArrayList<>();
        this.init = false;
        this.isParam = false;
    }

    public Pairs(Kind kind, String token, int line) {
        this.kind = kind;
        this.token = token;
        this.line = line;
        this.dim = 0;
        this.params = new ArrayList<>();
        this.init = false;
        this.isParam = false;
    }

    public Pairs(Kind kind, String token, String type, int line) {
        this.kind = kind;
        this.token = token;
        this.type = type;
        this.line = line;
        this.dim = 0;
        this.params = new ArrayList<>();
        this.init = false;
        this.isParam = false;
    }

    public Pairs(Kind kind, String token, String type, int line, int dim) {
        this.kind = kind;
        this.token = token;
        this.type = type;
        this.line = line;
        this.dim = dim;
        this.params = new ArrayList<>();
        this.init = false;
        this.isParam = false;
    }

    public String toString() {
        if (kind.equals(Kind.PARSE)) {
            if (!token.equals("BType") && !token.equals("Decl") && !(token.equals("BlockItem"))) {
                return '<' + token + '>' + '\n';
            } else {
                return "";
            }
        } else if (kind.equals(Kind.ERROR)) {
            return line + " " + token + '\n';
        } else {
            return kind + " " + token + '\n';
        }
    }

    public Kind getKind() {
        return kind;
    }

    public String getToken() {
        return token;
    }

    public int getLine() {
        return line;
    }

    public int getDim() {
        return dim;
    }

    public String getType() {
        return type;
    }

    public ArrayList<Pairs> getParams() {
        return this.params;
    }

    public void setKind(Kind kind) {
        this.kind = kind;
    }

    public void setToken(String token) {
        this.token = token;
    }

    public void setLine(int line) {
        this.line = line;
    }

    public void setType(String type) {
        this.type = type;
    }

    public void setDim(int dim) {
        this.dim = dim;
    }

    public void setValue(int value) {
        this.value = value;
        this.init = true;
    }

    public void setIsParam() {
        this.isParam = true;
    }

    public void setIsParam(Boolean param) {
        this.isParam = param;
    }

    public void setAddress(int address) {
        this.address = address;
    }

    public void setInit(Boolean init) {
        this.init = init;
    }

    public int getAddress() {
        return this.address;
    }

    public Boolean getIsParam() {
        return this.isParam;
    }

    public int getValue() {
        return this.value;
    }

    public Boolean getInit() {
        return this.init;
    }

    public void setParams(ArrayList<Pairs> params) {
        this.params = params;
    }

    public void setReg(String reg) {
        this.reg = reg;
    }

    public String getReg() {
        return this.reg;
    }

    public Pairs clone() {
        Pairs pairs = new Pairs(kind,token);
        pairs.setDim(dim);
        pairs.setParams(params);
        pairs.setIsParam(isParam);
        pairs.setAddress(address);
        pairs.setReg(reg);
        return pairs;
    }

    public enum Kind {
        IDENFR,
        INTCON,
        STRCON,
        MAINTK,
        CONSTTK,
        INTTK,
        BREAKTK,
        CONTINUETK,
        IFTK,
        ELSETK,
        NOT,
        AND,
        OR,
        WHILETK,
        GETINTTK,
        PRINTFTK,
        RETURNTK,
        PLUS,
        MINU,
        VOIDTK,
        MULT,
        DIV,
        MOD,
        LSS,
        LEQ,
        GRE,
        GEQ,
        EQL,
        NEQ,
        ASSIGN,
        SEMICN,
        COMMA,
        LPARENT,
        RPARENT,
        LBRACK,
        RBRACK,
        LBRACE,
        RBRACE,
        PARSE,
        VAL,
        VAR,
        FUNC,
        RET,
        ARRAY_VAL,
        ARRAY_VAR,
        NUM,
        ERROR
    }
}
